home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / ODMemMgr / Sources / MemHooks.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-03  |  9.9 KB  |  334 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MemHooks.cpp
  3.  
  4.     Contains:    Memory manager hook classes for debugging
  5.  
  6.     Owned by:    Michael Burbidge
  7.     Owned by:    Jens Alfke
  8.  
  9.     Copyright:    © 1993 - 1995-96 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.                   3/5/96    TWB        Comment out unused arguments to suppress warnings. 
  13.                  2/13/96    srf        Build variation for MacApp
  14.     
  15.          <9>      8/4/95    DM        Leak checking [1267956]
  16.          <8>      5/4/95    jpa        Added AboutToAllocate.
  17.          <7>    10/24/94    jpa        Constness [1194286]
  18.          <6>     9/29/94    RA        1189812: Mods for 68K build.
  19.          <5>     9/14/94    jpa        Eliminated dependencies on rest of OpenDoc.
  20.                                     [1186692]
  21.          <4>      8/8/94    jpa        DidAllocate doesn't offset ptr if it's NULL
  22.                                     [1179564]
  23.          <3>      8/8/94    jpa        Fixed realloc hooks.
  24.          <2>      8/2/94    jpa        Now supports realloc. Also optimized some
  25.                                     code, and fed different zap values into the
  26.                                     cushion blocks when deleting.
  27.          <1>     7/26/94    jpa        first checked in
  28.          
  29.     To Do:
  30.     In Progress:
  31.         
  32. */
  33.  
  34.  
  35. #ifndef _MEMCNFIG_
  36. #include "MemCnfig.h"
  37. #endif
  38.  
  39.  
  40. #if MM_DEBUG
  41.  
  42.  
  43. #ifndef _MEMHOOKS_
  44. #include "MemHooks.h"
  45. #endif
  46.  
  47. #ifndef _PLATFMEM_
  48. #include "PlatfMem.h"
  49. #endif
  50.  
  51. #ifndef _CRAWL_
  52. #include "Crawl.h"
  53. #endif
  54.  
  55.  
  56. //==============================================================================
  57. // CBlockCushionHook
  58. //==============================================================================
  59.  
  60. //------------------------------------------------------------------------------
  61. // CBlockCushionHook::CBlockCushionHook
  62. //------------------------------------------------------------------------------
  63.  
  64. CBlockCushionHook::CBlockCushionHook()
  65. {
  66. }
  67.  
  68. //------------------------------------------------------------------------------
  69. // CBlockCushionHook::~CBlockCushionHook
  70. //------------------------------------------------------------------------------
  71.  
  72. CBlockCushionHook::~CBlockCushionHook()
  73. {
  74. }
  75.  
  76. //------------------------------------------------------------------------------
  77. // CBlockCushionHook::GetHeaderSize
  78. //------------------------------------------------------------------------------
  79.  
  80. ODBlockSize CBlockCushionHook::GetHeaderSize()
  81. {
  82.     return kPrefixCushionLength;
  83. }
  84.  
  85. //------------------------------------------------------------------------------
  86. // CBlockCushionHook::AboutToAllocate
  87. //------------------------------------------------------------------------------
  88.  
  89. ODBlockSize CBlockCushionHook::AboutToAllocate(ODBlockSize size) const
  90. {
  91.     return size + kPrefixCushionLength + kSuffixCushionLength;
  92. }
  93.  
  94. //------------------------------------------------------------------------------
  95. // CBlockCushionHook::DidAllocate
  96. //------------------------------------------------------------------------------
  97.  
  98. void* CBlockCushionHook::DidAllocate(void* blk, ODBlockSize size)
  99. {
  100.     if( blk == kMMNULL )
  101.         return kMMNULL;
  102.     else {
  103.         unsigned long *prefix
  104.             = (unsigned long *) blk;
  105.         unsigned long *suffix
  106.             = (unsigned long *) ((char *) blk + size - kSuffixCushionLength);
  107.         
  108.         *prefix++ = kPrefixCushionMagicNumber;
  109.         *prefix++ = size;
  110.         *prefix++ = kPrefixCushionMagicNumber;
  111.             
  112.         *suffix = kSuffixCushionMagicNumber;
  113.     
  114.         return (char *) blk + kPrefixCushionLength;
  115.     }
  116. }
  117.  
  118. //------------------------------------------------------------------------------
  119. // CBlockCushionHook::AboutToBlockSize
  120. //------------------------------------------------------------------------------
  121.  
  122. const void* CBlockCushionHook::AboutToBlockSize(const void* blk)
  123. {
  124.     unsigned long *prefix = (unsigned long *) ((char*)blk - kPrefixCushionLength);
  125.     
  126.     if( prefix[0]!=kPrefixCushionMagicNumber || prefix[2]!=kPrefixCushionMagicNumber )
  127.         MM_WARN("Block %p's prefix is invalid",blk);
  128.     
  129.     unsigned long *suffix = (unsigned long *)
  130.         ((char*)prefix + prefix[1] - kSuffixCushionLength);
  131.     
  132.     if( *suffix != kSuffixCushionMagicNumber )
  133.         MM_WARN("Block %p's suffix is invalid",blk);
  134.  
  135.     return prefix;
  136. }
  137.  
  138. //------------------------------------------------------------------------------
  139. // CBlockCushionHook::BasicAboutToFree
  140. //------------------------------------------------------------------------------
  141.  
  142. unsigned long* CBlockCushionHook::BasicAboutToFree(void* blk, MMBoolean zap)
  143. {
  144.     unsigned long *prefix = (unsigned long *) ((char*)blk - kPrefixCushionLength);
  145.  
  146.     if( prefix[0]!=kPrefixCushionMagicNumber || prefix[2]!=kPrefixCushionMagicNumber )
  147.         MM_WARN("Block %p's prefix is invalid",blk);
  148.     
  149.     unsigned long *suffix = (unsigned long *)
  150.         ((char*)prefix + prefix[1] - kSuffixCushionLength);
  151.     
  152.     if( *suffix != kSuffixCushionMagicNumber )
  153.         MM_WARN("Block %p's suffix is invalid",blk);
  154.  
  155.     if( zap )
  156.         prefix[0] = prefix[2] = *suffix = 0xDDDDDDDD;        // Zap on free
  157.  
  158.     return prefix;
  159. }
  160.  
  161. //------------------------------------------------------------------------------
  162. // CBlockCushionHook::AboutToFree
  163. //------------------------------------------------------------------------------
  164.  
  165. void* CBlockCushionHook::AboutToFree(void* blk)
  166. {
  167.     return this->BasicAboutToFree(blk,kMMTrue);
  168. }
  169.  
  170. //------------------------------------------------------------------------------
  171. // CBlockCushionHook::AboutToRealloc
  172. //------------------------------------------------------------------------------
  173.  
  174. void CBlockCushionHook::AboutToRealloc(void* &blk , ODBlockSize &size)
  175. {
  176.     // The current block will be freed, and a new one allocated.
  177.     blk = this->BasicAboutToFree(blk,kMMFalse);        // Don't zap it, it might not get freed
  178.     size += kPrefixCushionLength + kSuffixCushionLength;
  179. }
  180.  
  181. //------------------------------------------------------------------------------
  182. // CBlockCushionHook::DidRealloc
  183. //------------------------------------------------------------------------------
  184.  
  185. void* CBlockCushionHook::DidRealloc(void* /*oldBlk*/, void* blk, ODBlockSize size)
  186. {
  187.     return this->DidAllocate(blk,size);
  188. }
  189.  
  190.  
  191.  
  192.  
  193. //==============================================================================
  194. // CBlockStackCrawlHook
  195. //==============================================================================\
  196.  
  197.  
  198. MMBoolean CBlockStackCrawlHook::gTrack;
  199.  
  200. // Global operator new/delete for StackCrawl objects
  201. #if !defined(qMacApp)
  202. // MacApp already has global new/delete of its own 
  203. void* operator new( size_t size )
  204. {
  205.     return MMAllocate(size);
  206. }
  207.  
  208. void operator delete( void* block )
  209. {
  210.     MMFree(block);
  211. }
  212. #endif
  213.  
  214. //------------------------------------------------------------------------------
  215. // CBlockStackCrawlHook::GetHeaderSize
  216. //------------------------------------------------------------------------------
  217.  
  218. ODBlockSize CBlockStackCrawlHook::GetHeaderSize()
  219. {
  220.     return sizeof(StackCrawl*);
  221. }
  222.  
  223. //------------------------------------------------------------------------------
  224. // CBlockStackCrawlHook::AboutToAllocate
  225. //------------------------------------------------------------------------------
  226.  
  227. ODBlockSize CBlockStackCrawlHook::AboutToAllocate(ODBlockSize size) const
  228. {
  229.     return size + sizeof(StackCrawl*);
  230. }
  231.  
  232. //------------------------------------------------------------------------------
  233. // CBlockStackCrawlHook::DidAllocate
  234. //------------------------------------------------------------------------------
  235.  
  236. void* CBlockStackCrawlHook::DidAllocate(void* blk, ODBlockSize /*size*/)
  237. {
  238.     if( blk == kMMNULL )
  239.         return kMMNULL;
  240.     else {
  241.         StackCrawl**stackCrawl = (StackCrawl**)blk;    // Points to where it's stored
  242.         if( gTrack ) {
  243.             gTrack = kMMFalse; // Disable to prevent recursion!
  244.             *stackCrawl = StackCrawl::New(3,-5);
  245.             gTrack = kMMTrue;
  246.         } else
  247.             *stackCrawl = 0;
  248.         return stackCrawl + 1;
  249.     }
  250. }
  251.  
  252. //------------------------------------------------------------------------------
  253. // CBlockStackCrawlHook::AboutToBlockSize
  254. //------------------------------------------------------------------------------
  255.  
  256. const void* CBlockStackCrawlHook::AboutToBlockSize(const void* blk)
  257. {
  258.     return ((StackCrawl**)blk) - 1;
  259. }
  260.  
  261. //------------------------------------------------------------------------------
  262. // CBlockStackCrawlHook::BasicAboutToFree
  263. //------------------------------------------------------------------------------
  264.  
  265. void* CBlockStackCrawlHook::BasicAboutToFree(void* blk, MMBoolean zap)
  266. {
  267.     StackCrawl** s = (StackCrawl**)blk - 1;
  268.     if( zap ) {
  269.         delete (StackCrawl*) ((size_t)(*s) & ~3);    // Delete crawl, mask lo bits
  270.         *s = (StackCrawl*) 0xDDDDDDDD;                // Zap on free
  271.     }
  272.     return s;
  273. }
  274.  
  275. //------------------------------------------------------------------------------
  276. // CBlockStackCrawlHook::AboutToFree
  277. //------------------------------------------------------------------------------
  278.  
  279. void* CBlockStackCrawlHook::AboutToFree(void* blk)
  280. {
  281.     return this->BasicAboutToFree(blk,kMMTrue);
  282. }
  283.  
  284. //------------------------------------------------------------------------------
  285. // CBlockStackCrawlHook::AboutToRealloc
  286. //------------------------------------------------------------------------------
  287.  
  288. void CBlockStackCrawlHook::AboutToRealloc(void* &blk , ODBlockSize &size)
  289. {
  290.     // The current block will be freed, and a new one allocated.
  291.     blk = this->BasicAboutToFree(blk,kMMFalse);        // Don't zap it, it might not get freed
  292.     size += sizeof(StackCrawl*);
  293. }
  294.  
  295. //------------------------------------------------------------------------------
  296. // CBlockStackCrawlHook::DidRealloc
  297. //------------------------------------------------------------------------------
  298.  
  299. void* CBlockStackCrawlHook::DidRealloc(void* /*oldBlk*/, void* blk, ODBlockSize size)
  300. {
  301.     return this->DidAllocate(blk,size);
  302. }
  303.  
  304. //------------------------------------------------------------------------------
  305. // CBlockStackCrawlHook::GetType
  306. //------------------------------------------------------------------------------
  307.  
  308. long CBlockStackCrawlHook::GetType( ) const
  309. {
  310.     return kBlockStackCrawlHookType;
  311. }
  312.  
  313. //------------------------------------------------------------------------------
  314. // CBlockStackCrawlHook::GetStackCrawl
  315. //------------------------------------------------------------------------------
  316.  
  317. StackCrawl* CBlockStackCrawlHook::GetStackCrawl(const void* blk) const
  318. {
  319.     return * (StackCrawl**) blk;
  320. }
  321.  
  322. //------------------------------------------------------------------------------
  323. // CBlockStackCrawlHook::SetStackCrawl
  324. //------------------------------------------------------------------------------
  325.  
  326. void CBlockStackCrawlHook::SetStackCrawl(const void* blk, StackCrawl* s)
  327. {
  328.     * (StackCrawl**) blk = s;
  329. }
  330.  
  331.  
  332.  
  333.  
  334. #endif /*MM_DEBUG*/